package com.headwind.multi.datasource.holder;

import com.headwind.multi.datasource.annotation.TargetDataSource;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author : Headwind
 * @version : 1.0
 * @date : Created in 2020/8/13
 * @description : 数据源拦截器
 */
@Log4j2
@Aspect
@Component
public class DynamicDataSourceAspect {
    /**
     * 对设定{@link TargetDataSource}注解的方法进行拦截
     *
     * @param pjp 方法拦截器
     * @return 方法的实行结果
     * @throws Throwable 异常
     */
    @Around(value = "@annotation(com.headwind.multi.datasource.annotation.TargetDataSource)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //方法对象取得
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method targetMethod = methodSignature.getMethod();
        if (targetMethod.isAnnotationPresent(TargetDataSource.class)) {
            // 获取方法注解及注解使用的数据源
            String targetDataSource = targetMethod.getAnnotation(TargetDataSource.class).dataSource();
            log.info("---- 当前使用的数据源是：" + targetDataSource + "。");
            // 设定当前方法所使用的数据源
            DynamicDataSourceHolder.setDataSource(targetDataSource);
        }
        try {
            // 实行当前方法并返回结果
            return pjp.proceed();
        } finally {
            // 清除当前方法线程的数据源
            log.info("----- 当前数据源已经清除并恢复到默认数据源中。。。");
            DynamicDataSourceHolder.clearDataSource();
        }
    }

}
